package com.spring.sd;

import com.spring.sd.aware.MyBean;
import com.spring.sd.aware.MyConfig1;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * 失效的 @Autowired 注解
 * 在某些情况下，尽管容器中存在必要的后置处理器，但 @Autowired 和 @PostConstruct 注解也会失效。
 *
 */
public class AwareApplication2 {

    public static void main(String[] args) {
        //step1();
        step2();

    }

    public static void step1() {
        // @Autowired 和 @PostConstruct 注解成功被解析。
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("myConfig1", MyConfig1.class);
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        // 解析配置类中的注解
        context.registerBean(ConfigurationClassPostProcessor.class);

        context.refresh();
        context.close();
    }

    public static void step2() {
        // 在 Config1 中添加了一个被 @Bean 注解标记的 processor1() 方法，用于向容器中添加 BeanFactoryPostProcessor。
        // processor1() 方法成功生效，但 @Autowired 和 @PostConstruct 注解的解析失败了。
        /**
         * 对于 context.refresh(); 方法来说，它主要按照以下顺序干了三件事：
         *
         * 执行 BeanFactory 后置处理器；
         * 添加 Bean 后置处理器；
         * 创建和初始化单例对象。
         * 比如当 Java 配置类不包括 BeanFactoryPostProcessor 时：BeanFactoryPostProcessor 会在 Java 配置类初始化之前执行。
         * 当 Java 配置类中定义了 BeanFactoryPostProcessor 时，如果要创建配置类中的 BeanFactoryPostProcessor 就必须提前创建和初始化Java配置类。
         *
         * 在创建和初始化 Java 配置类时，由于 BeanPostProcessor 还未准备好，无法解析配置类中的 @Autowired 等注解，导致 @Autowired 等注解失效：
         *
         */
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("myConfig1", MyConfig1.class);
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        // 解析配置类中的注解
        context.registerBean(ConfigurationClassPostProcessor.class);

        context.refresh();
        context.close();
    }
}
